//
// Created by Martin on 2023/2/10.
//

#ifndef MUDUO_IOFILE_H
#define MUDUO_IOFILE_H

#include "muduo/base/noncopyable.h"
#include "OsFile.h"

#include <vector>
#include <string>
#include <fstream>
#include <map>
#include <mutex>
#include <memory>

namespace ftp {
namespace filesystem {

/// Wrapper of std::fstream
class IoFileStream
{
public:
    IoFileStream(const std::string& pathname, std::ios::openmode mode);
    ~IoFileStream();

    // delete copy
    IoFileStream(const IoFileStream& ) = delete;
    IoFileStream& operator=(const IoFileStream& ) = delete;

    void read(char* buf, ssize_t size);
    void write(const char* buf, ssize_t size);

    void close();
    void flush();
    bool good();
    bool eof();
    bool fail();
    bool is_open();
    ssize_t gcount();
    void seekg(ssize_t pos);
    void seekg(ssize_t offset, std::ios_base::seekdir dir);

    void setBuffer(std::vector<char>& buffer);

private:
    std::unique_ptr<std::fstream> stream_;
    const std::string path_;
    bool lockFile_;
};

/// RAII file stream
struct IoFile
{
    IoFile(const std::string &pathname, std::ios::openmode mode)
            : fileStream_(pathname, mode), streamBuffer_(1024 * 1024 * 1) // 1MB
    {
#if 0
        fileStream_.rdbuf()->pubsetbuf(&streamBuffer_[0],
                static_cast<long>(streamBuffer_.size())); // set buffer for file stream
#endif
        fileStream_.setBuffer(streamBuffer_);
    }

    IoFile() = delete;
    IoFile(const IoFile &) = delete;

    ~IoFile()
    {
        fileStream_.close();
        fileStream_.flush();
    }

//    std::fstream fileStream_;
    IoFileStream fileStream_;
    std::vector<char> streamBuffer_;
};

} // namespace filesystem
} // namespace ftp

#endif //MUDUO_IOFILE_H
